package com.sparkseries.common.security.config;

import com.sparkseries.common.security.domain.IgnoreUrls;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 忽略Security安全拦截资源获取配置
 */
@Configuration
public class SecurityIgnoreUrlsConfig {
    // 资源获取地址
    private static final String CONFIG_PATTERN = "classpath*:ignore-urls.yml";
    // key名称
    private static final String IGNORE_URLS_KEY = "urls";

    @Bean
    public IgnoreUrls IgnoreUrls() {
        return new IgnoreUrls(loadIgnoreUrls());
    }

    /**
     * 加载所有配置文件的忽略URL列表
     */
    private List<String> loadIgnoreUrls() {
        try {
            Resource[] resources = loadConfigResources();
            return parseResources(resources);
        } catch (IOException e) {
            return Collections.emptyList();
        }
    }

    /**
     * 加载配置文件资源
     */
    private Resource[] loadConfigResources() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        return resolver.getResources(CONFIG_PATTERN);
    }

    /**
     * 解析所有资源文件
     */
    private List<String> parseResources(Resource[] resources) {
        return Stream.of(resources)
                .map(this::parseYamlResource)
                .filter(Objects::nonNull)
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 解析单个YAML文件
     */
    private List<String> parseYamlResource(Resource resource) {
        try (InputStream input = resource.getInputStream()) {
            Yaml yaml = new Yaml();
            Map<String, Object> yamlMap = yaml.load(input);
            return extractUrls(yamlMap);
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    /**
     * 提取忽略URL列表
     */
    private List<String> extractUrls(Map<String, Object> yamlMap) {
        Object urlsObj = yamlMap.get(IGNORE_URLS_KEY);
        if (urlsObj instanceof List) {
            return ((List<?>) urlsObj).stream()
                    .filter(String.class::isInstance)
                    .map(String.class::cast)
                    .collect(Collectors.toList());
        }
        return Collections.emptyList();
    }
}